package com.kx.game.center.common.enums;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.kx.game.center.utils.Assert;

/**
 * 从0开始的可索引每句借口定义，实现此接口的每句各元素的index可以不连续，但此接口的实现多为稀疏数组结构，保持index连续可以节省空间
 * 
 * @author wenji.fan
 * @since 2013年8月5日
 * 
 */
public interface IndexedEnum {
	public static final Log logger = LogFactory.getLog(IndexedEnum.class);

	/**
	 * 获取该枚举的索引值
	 * 
	 * @return
	 */
	public abstract int getIndex();

	public static class IndexedEnumUtil {
		public static final Log logger = LogFactory.getLog(IndexedEnum.class);
		/**
		 * 索引警戒上限，发现超过此值的索引可能存在较大的空间浪费
		 */
		private static final int WARNNING_MAX_INDEX = 1000;

		public static <E extends IndexedEnum> List<E> toIndexes(E[] enums) {
			int maxIndex = Integer.MIN_VALUE;
			int curIdx = 0;
			for (E enm : enums) {
				curIdx = enm.getIndex();
				Assert.isTrue(curIdx >= 0, String.format(
						"枚举索引不能为负index:%1$d type: %2$s", curIdx, enums
								.getClass().getComponentType().getName()));
				if (curIdx > maxIndex) {
					maxIndex = curIdx;
				}
			}

			if (maxIndex >= WARNNING_MAX_INDEX) {
				logger.warn("警告:枚举类" + enums.getClass().getComponentType().getName() + "中有超过" +
						WARNNING_MAX_INDEX + "的索引，如果有很多索引空缺，可能会造成空间浪费");
			}
			List<E> instances = new ArrayList<>(maxIndex + 1);

			// 先全用null填充
			for (int i = 0; i < maxIndex + 1; i++) {
				instances.add(null);
			}

			for (E enm : enums) {
				curIdx = enm.getIndex();
				Assert.isTrue(instances.get(curIdx) == null,
						"枚举中有重复的index type="
								+ enums.getClass().getComponentType().getName());
				instances.set(curIdx, enm);
			}
			return instances;
		}
	}
}
